package com.hzjq.rxblast.ui

import android.content.Context
import android.content.Intent
import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager
import com.github.mikephil.charting.components.Description
import com.github.mikephil.charting.components.XAxis.XAxisPosition
import com.github.mikephil.charting.components.YAxis
import com.github.mikephil.charting.data.Entry
import com.github.mikephil.charting.data.LineData
import com.github.mikephil.charting.data.LineDataSet
import com.hzjq.core.Blast
import com.hzjq.core.bean.ChargeProgressEntity
import com.hzjq.core.bean.ErrorCapEntity
import com.hzjq.core.bean.ErrorReadCapEntity
import com.hzjq.core.bean.ErrorResult
import com.hzjq.core.callback.Callback
import com.hzjq.core.callback.ProgressCallback
import com.hzjq.core.event.PioUnEnableEvent
import com.hzjq.rxblast.R
import com.hzjq.rxblast.adapter.RegisterAdapter
import com.hzjq.rxblast.event.LogEvent
import com.hzjq.rxblast.wiget.ElectricYValueFormatter
import com.hzjq.rxblast.wiget.VoltageXValueFormatter
import com.lxj.xpopup.XPopup
import com.lxj.xpopup.core.BasePopupView
import com.lxj.xpopup.interfaces.OnConfirmListener
import com.wxl.common.base.AbsActivity
import com.wxl.common.util.Toll
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.functions.Consumer
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.activity_charge_layout.*
import kotlinx.android.synthetic.main.activity_register_cap_layout.*
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.util.concurrent.TimeUnit


class ChargeActivity : AbsActivity() {

    companion object {
        fun start(context: Context, caps: ArrayList<ErrorCapEntity>,maxDelay:Long) {
            val intent = Intent(context, ChargeActivity::class.java)
            intent.putExtra("caps", caps)
            intent.putExtra("maxDelay",maxDelay)
            context.startActivity(intent)
        }
    }

    private var maxDelay = 0L
    private val caps = arrayListOf<ErrorCapEntity>()
    private val registerResultCaps = arrayListOf<ErrorCapEntity>()
    private val mRegisterAdapter = RegisterAdapter(arrayListOf())
    private var disposable: Disposable? = null
    private var chartDisposable: Disposable? = null
    private var count = 0
    private val yVals1 = arrayListOf<Entry>()
    private var mVoltage = 0
    private var mElectric = 0f
    private var curTime = 0
    private var isChargeEnd = false
    private var isStartCharge = false
    private var warnPopupView : BasePopupView? = null

    override fun getCreateContentViewId(): Int {
        return R.layout.activity_charge_layout
    }

    override fun onCreateViewChanged() {
        maxDelay = intent.getLongExtra("maxDelay",0)
        caps.clear()
        caps.addAll(intent.getSerializableExtra("caps") as ArrayList<ErrorCapEntity>)
        chargeCapView.layoutManager = LinearLayoutManager(this)
        chargeCapView.adapter = mRegisterAdapter
        chargeProgressBar.max = 100
        cancelCharge()
        onChargeChart()
        chargeCap()
        onToBlast()
    }

    private fun onToBlast() {
        chargeToBlast.setOnClickListener {
            chargeToBlast.isEnabled = false
            chargeToBlast.isClickable = false
            chartDisposable?.dispose()
            BlastActivity.start(this,maxDelay,caps)
            finish()
        }
    }

    @Synchronized
    private fun chargeCap() {
        if(isStartCharge){
           return
        }
        isStartCharge  = true
        EventBus.getDefault().post(LogEvent("开始充电"))
        Blast.getInstance().charge()
            .onCharge(object : ProgressCallback<ChargeProgressEntity> {
                override fun onError(errorCode: ErrorResult) {
                    chartDisposable?.dispose()
                    chargeProgressAction.text = "${errorCode.errorAction}..."
                }

                override fun onProgressChanged(progress: Int, total: Int, action: String) {
                    //chargeProgressBar.max = total
                    chargeProgressBar.progress = progress
                    chargeProgressAction.text = "${action}..."
                }

                override fun onResult(t: ChargeProgressEntity) {
                    (t.mVoltage.toString() + "V").also { chargeCapDy.text = it }
                    (t.mElectric.toString() + "mA").also { chargeCapDl.text = it }
                    this@ChargeActivity.mElectric = t.mElectric
                    if (t.code == 0) {
                        if (t.isEnd) {
                            isStartCharge = false
                            isChargeEnd = true
                            EventBus.getDefault().post(LogEvent("充电完成"))
                            convertOkCap()
                        }
                    }
                }

                override fun onRetryCountChanged(retryCount: Int, action: String) {
                    chargeProgressAction.text = "${action}${retryCount}次..."
                }

            }, Consumer {
                if(it.caps[it.caps.size - 1].isScanEnd) {
                    chartDisposable?.dispose()
                    convertErrorCap(it)
                    showCaps()
                }
            })
    }

    private fun convertErrorCap(result: ErrorReadCapEntity) {
        disposable?.dispose()
        disposable = Observable.create<MutableList<ErrorCapEntity>>() {
            val temp = arrayListOf<String>()
            registerResultCaps.clear()
            result.errors.forEach {
                if(!temp.contains(it.cap!!.uid)){
                    temp.add(it.cap!!.uid)
                    registerResultCaps.add(it)
                }
            }
            temp.clear()
            it.onNext(registerResultCaps)
        }.subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                chargeOkCount.text = "已完成:0"
                chargeWaiteCount.text = "失败:${registerResultCaps.size}"
                showCaps()
            }
    }

    private fun showCaps() {
        chargeProgressLayout.visibility = View.GONE
        chargeCapView.visibility = View.VISIBLE
        mRegisterAdapter.setNewInstance(registerResultCaps)
    }


    private fun convertOkCap() {
        chargeProgressAction.text = "正在组装雷管信息..."
        registerResultCaps.clear()
        registerResultCaps.addAll(caps)
        chargeOkCount.text = "已完成:${registerResultCaps.size}"
        chargeWaiteCount.text = "失败:0"
        chargeToBlast.visibility = View.VISIBLE
        showCaps()
    }


    private fun cancelCharge() {
        chargeCancel.setOnClickListener {
            if (warnPopupView != null && warnPopupView!!.isShow) {
                return@setOnClickListener
            }
            warnPopupView =    XPopup.Builder(this)
                .dismissOnTouchOutside(false)
                .dismissOnBackPressed(false)
                .asConfirm("警告", "雷管已充入高压，请按相关规定进行执行！",
                    OnConfirmListener {
                        turnVoltage()
                    }).show()
        }
    }


    private fun turnVoltage() {
        val show = XPopup.Builder(this)
            .hasShadowBg(false)
            .asLoading("正在退出...")
            .show()
        Blast.getInstance().charge()
            .onCloseElectric(object : Callback<Boolean> {
                override fun onError(errorCode: ErrorResult) {
                    show.dismiss()
                    Toll.toll("退出失败")
                }

                override fun onResult(t: Boolean) {
                    show.dismiss()
                    if (t) {
                        Blast.getInstance().charge().cancel()
                        chartDisposable?.dispose()
                        finish()
                    } else {
                        Toll.toll("退出失败")
                    }
                }

                override fun onRetryCountChanged(
                    retryCount: Int,
                    action: String
                ) {

                }

            })
    }


    private fun onChargeChart() {
        val mDescription = Description()
        mDescription.text = ""
        chargeChart.setDescription(mDescription)
        chargeChart.setPinchZoom(true) //挤压缩放
        chargeChart.setDrawGridBackground(false)
        chargeChart.setScaleYEnabled(false)
        chargeChart.setDoubleTapToZoomEnabled(false) //双击缩放
        chargeChart.getXAxis().setPosition(XAxisPosition.BOTTOM) //x轴位置

        val leftAxis: YAxis = chargeChart.getAxisLeft()
        leftAxis.valueFormatter = ElectricYValueFormatter() //自定义y数据格式化方式
        leftAxis.setDrawGridLines(false) //是否画线
        leftAxis.spaceTop = 10f
        leftAxis.setAxisMinValue(0f)
        chargeChart.getAxisRight().setEnabled(false)
        //设置一页显示的数据条数，超出的数量需要滑动查看：

        chargeChart.xAxis.valueFormatter = VoltageXValueFormatter()

        yVals1.add(Entry(curTime.toFloat(), mElectric))
        val mLineDataSet = LineDataSet(yVals1, "")
        val mLineData = LineData(mLineDataSet)
        chargeChart.data = mLineData
        chargeChart.setVisibleXRangeMaximum(5f)//需要在设置数据源后生效
        startChartData()
    }


    private fun startChartData() {
        chartDisposable = Observable.interval(2, TimeUnit.SECONDS,Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeOn(Schedulers.newThread())
            .subscribe {
                notifyElectricVoltageDataChanged()
            }
    }


    private fun notifyElectricVoltageDataChanged() {
        curTime += 2
        yVals1.add(Entry(curTime.toFloat(), mElectric))
        val mLineDataSet = LineDataSet(yVals1, "")
        val mLineData = LineData(mLineDataSet)
        chargeChart.data = mLineData
        chargeChart.setVisibleXRangeMaximum(10f)//需要在设置数据源后生效
        chargeChart.moveViewToX(curTime.toFloat())
        chargeChart.invalidate()
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onPioUnEnableEvent(e: PioUnEnableEvent){
        showPioUnEnablePop(this)
    }


    override fun getPageTitle(): String {
        return "雷管充电"
    }

    override fun onBackClick(): Boolean {
        chargeCancel.performClick()
        return false
    }

    override fun onBackPressed() {
        chargeCancel.performClick()
    }

    override fun onDestroy() {
        super.onDestroy()
        Blast.getInstance().charge().cancel()
        disposable?.dispose()
        chartDisposable?.dispose()
    }
}